#pragma once
#include "DXAMLCommon.h"


#include "IXamlSchemaObject.h"
#include "XamlTypeToken.h"
#include "XamlPropertyToken.h"
#include "XamlTextSyntax.h"
#include "XamlProperty.h"
#include "XamlBitSet.h"
#include "XamlPropertyAndTypeToken.h"
#include "XamlCommonServiceProviderContext.h"


class XamlSchemaContext;
class XamlNamespace;
class XamlCommonServiceProviderContext;


class XamlType :
	public IXamlSchemaObject
{
protected: 
	XamlType(const xshared_ptr<XamlSchemaContext> & spSchemaContext, const xshared_ptr<XamlNamespace> & spNamespace, const struct XamlTypeToken sTypeToken, const xshared_ptr<CXString> & inTypeName);
	XamlType();
public: 
	HRESULT CreateInstance(xshared_ptr<XamlQualifiedObject> & rqoOut);
	HRESULT CreateFromValue(xshared_ptr<XamlCommonServiceProviderContext> spTextSyntaxContext, const xshared_ptr<XamlTextSyntax> & spTextSyntax, const xshared_ptr<XamlQualifiedObject> & qoValue, xshared_ptr<XamlQualifiedObject> & rqoOut);
	XBOOL Equals(const xshared_ptr<XamlType> & spType);
	static XBOOL AreEqual(const xshared_ptr<XamlType> & spFirst, const xshared_ptr<XamlType> & spSecond);
	HRESULT IsUnknown(XBOOL & outValue);
	HRESULT IsPublic(XBOOL & outValue);
	HRESULT IsConstructible(XBOOL & outValue);
	HRESULT IsString(XBOOL & outValue);
	HRESULT IsCollection(XBOOL & outValue);
	HRESULT IsList(XBOOL & outValue);
	HRESULT IsDictionary(XBOOL & outValue);
	HRESULT IsArray(XBOOL & outValue);
	HRESULT IsMarkupExtension(XBOOL & outValue);
	HRESULT IsTemplate(XBOOL & outValue);
	HRESULT IsDirective(XBOOL & outValue);
	HRESULT IsNullable(XBOOL & outValue);
	HRESULT TrimSurroundingWhitespace(XBOOL & outValue);
	HRESULT IsWhitespaceSignificantCollection(XBOOL & outValue);
	HRESULT UsableDuringInitialization(XBOOL & outValue);
	HRESULT IsISupportInitialize(XBOOL & outValue);
	HRESULT get_Name(xshared_ptr<CXString> & outName);
	HRESULT get_FullName(xshared_ptr<CXString> & outFullName);
	HRESULT get_TextSyntax(xshared_ptr<XamlTextSyntax> & outTextSyntax);
	HRESULT get_ContentProperty(xshared_ptr<XamlProperty> & outContentProperty);
	HRESULT get_ContentWrapper(xshared_ptr<XamlType> & spContentWrapperType);
	HRESULT get_RuntimeNameProperty(xshared_ptr<XamlProperty> & outRuntimeNameProperty);
	HRESULT get_XmlLangProperty(xshared_ptr<XamlProperty> & outXmlLangProperty);
	HRESULT get_DictionaryKeyProperty(xshared_ptr<XamlProperty> & outDictionaryKeyProperty);
	HRESULT get_BaseType(xshared_ptr<XamlType> & outBaseType);
	HRESULT get_MarkupExtensionReturnType(xshared_ptr<XamlType> &);
	HRESULT get_MarkupExtensionExpressionType(xshared_ptr<XamlType> &);
	const struct XamlTypeToken & get_TypeToken();
	HRESULT GetProperty(const xshared_ptr<CXString> & inPropertyName, xshared_ptr<XamlProperty> & outProperty);
	HRESULT GetDependencyProperty(const xshared_ptr<CXString> & inPropertyName, xshared_ptr<XamlProperty> & outProperty);
	HRESULT GetAttachableProperty(const xshared_ptr<CXString> & inPropertyName, xshared_ptr<XamlProperty> & outProperty);
	HRESULT GetXamlNamespace(xshared_ptr<XamlNamespace> & outNamespace);
	HRESULT IsAssignableFrom(const xshared_ptr<XamlType> & xamlType, XBOOL & bIsAssignableFrom);
	XUINT32 get_RuntimeIndex();
	HRESULT SetRuntimeIndex(XUINT32 uiRuntimeIndex);
	void SetIsDirective();
private: 
	void SetBoolTypeBit(enum BoolTypeBits fTypeBit, XUINT32 bValue);
	void SetBoolTypeBits(const XamlBitSet<enum BoolTypeBits> & fTypeBits, const XamlBitSet<enum BoolTypeBits> & fValueBits);
	HRESULT GetBoolTypeBit(enum BoolTypeBits fTypeBit, XUINT32 & fValue);
	HRESULT RetrieveBoolTypeBits(const XamlBitSet<enum BoolTypeBits> & fTypeBits);
	HRESULT TryGetPropertyFromCache(const xshared_ptr<CXString> & inPropertyName, struct XamlPropertyAndTypeToken & tPropertyAndType);
	HRESULT AddPropertyToCache(const xshared_ptr<CXString> & inPropertyName, struct XamlPropertyAndTypeToken & tPropertyAndType);
	HRESULT TryGetDependencyPropertyFromCache(const xshared_ptr<CXString> & inPropertyName, struct XamlPropertyAndTypeToken & tPropertyAndType);
	HRESULT AddDependencyPropertyToCache(const xshared_ptr<CXString> & inPropertyName, struct XamlPropertyAndTypeToken & tPropertyAndType);
protected: 
	HRESULT GetSchemaContext(xshared_ptr<XamlSchemaContext> & outSchemaContext);

private: 
	xweak_ptr<XamlSchemaContext> m_spXamlSchemaContext; 
	xshared_ptr<XamlTextSyntax> m_spXamlTextSyntax; 
	xshared_ptr<CXString> m_spName; 
	xshared_ptr<CXString> m_spFullName; 
	xshared_ptr<XamlProperty> m_spRuntimeName;  
	xshared_ptr<XamlProperty> m_spContentProperty;
	xshared_ptr<XamlType> m_spContentWrapper; 
	xweak_ptr<XamlNamespace> m_spXamlNamespace; 
	xstringmap<XamlPropertyAndTypeToken> m_PropertyCache; 
	xstringmap<XamlPropertyAndTypeToken> m_DependencyPropertyCache; 
	XamlBitSet<enum BoolTypeBits> m_flagsBoolTypeBits; 
	XamlBitSet<enum BoolTypeBits> m_flagsBoolTypeValidBits; 
	struct XamlTypeToken m_sTypeToken; 
	XamlBitSet<enum NonBoolTypeValidBits> m_flagsNonBoolTypeValidBits; 
	struct XamlTypeToken m_sBaseTypeToken; 
	XBOOL m_bHasContentProperty;
	XUINT32 m_uiRuntimeIndex;

};


